using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;

public struct CtrlMsg
{
    public string cmd;
    public object[] args;
    public CtrlMsg(string cmdStr, params object[] vs)
    {
        cmd  = cmdStr;
        args = vs;
    }
}

public class CallSystem
{
    public delegate object FuncMsgDelegate(CtrlMsg msg);
    public delegate object FuncStrDelegate(string cmd);
    public delegate object FuncNotDelegate();

    public delegate bool CheckMsgDelegate(CtrlMsg msg, ref object result);
    public delegate bool CheckStrDelegate(string msg,  ref object result);

    private static UnityEvent<CtrlMsg>     ActionCall  = new UnityEvent<CtrlMsg>();
    private static List<CheckStrDelegate>  argLists    = new List<CheckStrDelegate>();
    private static List<CheckMsgDelegate>  methodLists = new List<CheckMsgDelegate>();



    public static void AddMethodListener(CheckMsgDelegate call)
    {
        if(methodLists.Contains(call) == false)
            methodLists.Add(call);
        else
        { 
            Debug.LogError("重复注册，返回值事件具有唯一性 ,请检查");
        }
    }

    public static void RemoveMethodListener(CheckMsgDelegate call)
    {
        if (methodLists.Contains(call))
            methodLists.Remove(call);
        else
        {
            Debug.LogError("重复移除");
        }
    }

    public static void AddListener(UnityAction<CtrlMsg> call)
    {
        ActionCall.AddListener(call);
    }

    public static void RemoveListener(UnityAction<CtrlMsg> call)
    {
        ActionCall.RemoveListener(call);
    }

    public static void AddFuncListener(CheckStrDelegate  call)
    {
        if (argLists.Contains(call) == false)
            argLists.Add(call);
        else
        {
            Debug.LogError("重复注册，返回值事件具有唯一性 ,请检查");
        }
    }

    public static void RemoveFuncListener(CheckStrDelegate call)
    {
        if (argLists.Contains(call))
            argLists.Remove(call);
        else
        {
            Debug.LogError("重复移除");
        }
    }


    public static void Invoke(CtrlMsg msg)
    {
        ActionCall?.Invoke(msg);
    }

    public static void Invoke(string cmd, params object[] vs)
    {
        Invoke(new CtrlMsg(cmd, vs));
    }


    public static object InvokeField(string cmd)
    {
       return InvokeField(new CtrlMsg(cmd));
    }

    public static object InvokeField(CtrlMsg msg)
    {
        object resulf = null;
        foreach (var item in argLists)
        {
            var isValue = item(msg.cmd, ref resulf);
            if (isValue) return resulf;
        }

        Debug.LogError("事件还未注册");
        return null;
    }


    public static object InvokeMethod(CtrlMsg msg)
    {
        object resulf = null;
        foreach (var item in methodLists)
        {
            var isValue = item(msg, ref resulf);
            if (isValue) return resulf;
        }

        Debug.LogError("事件还未注册");
        return null;
    }

    public static object InvokeMethod(string cmd, params object[] vs)
    {
        var msg = new CtrlMsg(cmd, vs);
        return InvokeMethod(msg);
    }
}



[System.AttributeUsage(System.AttributeTargets.Method)]
public class AcitonAttribute : System.Attribute, IMethod
{
    public string Cmd{ get;  set;}
    public AcitonAttribute(string cmd = "")
    {
        Cmd = cmd;
    }
}


[System.AttributeUsage(System.AttributeTargets.Method)]
public class FuncAttribute : System.Attribute, IMethod
{
    public string Cmd { get; set; }
    public FuncAttribute(string cmd = "")
    {
        Cmd = cmd;
    }
}


[System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property)]
public class ArgAttribute : System.Attribute, IMethod
{
    public string Cmd { get; set; }
    public ArgAttribute(string cmd = "")
    {
        Cmd = cmd;
    }
}

